<?php

namespace api\modules\app\services;

use api\modules\app\models\DeployDetail;
use api\modules\app\models\MetaArea;
use api\modules\app\models\QrcodeDeploy;
use api\modules\app\models\Section;
use api\modules\app\models\Unit;
use api\utils\ExportUtil;
use api\utils\StringUtil;
use Yii;
use yii\data\ActiveDataProvider;
use yii\data\Pagination;
use yii\db\Query;
use yii\grid\GridView;
use yii\helpers\ArrayHelper;

class DeployService
{
    public function create($params, $opter)
    {
        $metas = $params['metas'];
        $deployType = $params['type'] ?? 'section';
        $eventTypes = $params['eventTypes'];
        $unitCodes = $params['unitCodes'];
        $request = $params;
        unset($request['unitCodes']);
        $plan = new QrcodeDeploy([
            'user_id' => $opter['id'],
            'user_name' => $opter['username'],
            'event_type_count' => count($params['eventTypes']),
            'request' => json_encode($request),
        ]);
        $plan->save();
        $count = 0;
        $bind = 0;
        $selectStreets = [];
        $selectGrids = [];
        foreach ($metas as $meta) {
            $districtCode = $meta[0];
            $streetCode = $meta[1] ?? '';
            $communityCode = $meta[2] ?? '';
            $estateCode = $meta[3] ?? '';
            $gridCode = '';
            if (empty($streetCode)) { // 整个区所有街道
                $disUnitCodes = $unitCodes[$districtCode] ?? [];
                list($unitCount, $bindCount) = $this->batchCreate($plan, $eventTypes,
                                                        $districtCode, $streetCode, $communityCode, $estateCode, $gridCode,
                                                        $disUnitCodes, $deployType);
                $count += $unitCount;
                $bind += $bindCount;
                continue;
            }
            !in_array($streetCode, $selectStreets) && array_push($selectStreets, $streetCode);
            if (empty($communityCode)) { // 部署整个街道
                $strUnitCodes = $unitCodes[$streetCode] ?? [];
                list($unitCount, $bindCount) = $this->batchCreate($plan, $eventTypes, $districtCode, $streetCode, $communityCode, $estateCode, $gridCode, $strUnitCodes, $deployType);
                $count += $unitCount;
                $bind += $bindCount;
                continue;
            }

            if (empty($estateCode)) { // 部署整个居委
                $strUnitCodes = $unitCodes[$streetCode] ?? [];
                list($unitCount, $bindCount) = $this->batchCreate($plan, $eventTypes, $districtCode, $streetCode, $communityCode, $estateCode, $gridCode, $strUnitCodes, $deployType);
                $count += $unitCount;
                $bind += $bindCount;
                continue;
            }
            $gridUnitCodes = $unitCodes[$gridCode] ?? [];
            list($unitCount, $bindCount) = $this->batchCreate($plan, $eventTypes, $districtCode, $streetCode, $gridCode, $gridUnitCodes, $deployType);
            // !in_array($gridCode, $selectGrids) && array_push($selectGrids, $gridCode);
            // $gridUnitCodes = $unitCodes[$gridCode] ?? [];
            // list($unitCount, $bindCount) = $this->batchCreate($plan, $eventTypes, $districtCode, $streetCode, $gridCode, $gridUnitCodes, $deployType);
            $count += $unitCount;
            $bind += $bindCount;
        }

        // $district = MetaArea::findOne(['code' => $districtCode, 'status' => 1, 'category' => '区']);
        $plan->setAttributes([
            'district' => $districtCode,
            'district_name' => '',//$district->name,
            'street_count' => count($selectStreets),
            'grid_count' => ($deployType == 'grid') ? count($selectGrids) : 0,
            'bind_unit_count' => $bind,
            'unit_count' => $count,
            'state' => $bind == $count ? 1 : 0,
        ]);
        $plan->save();

        return $plan;
    }

    public function countUnit($params)
    {
        $metas = $params['metas'];
        $deployType = $params['type'] ?? 'grid';
        $eventTypes = $params['eventTypes'];
        $codes = ArrayHelper::getColumn($metas, 2);
        $condition = [
            'event_type3_code' => $eventTypes,
            'status' => UnitService::STATUS_ENABLED,
        ];
        if ($deployType == 'grid') {
            $condition['grid_code'] = $codes;
            return Unit::find()->andFilterWhere($condition)->count();
        }
        $sections = Section::findAll(['code' => $codes]);
        $count = 0;
        foreach ($sections as $section) {
            $count += Unit::find()->andFilterWhere(array_merge($condition, [
                'section' => $section->name,
                'section_start' => $section->start,
                'section_end' => $section->end,
            ]))->count();
        }
        return $count;
    }

    public function batchCreate(QrcodeDeploy $plan, $eventTypes, $districtCode, $streetCode = null, $communityCode = null, $estateCode = null, $gridCode = null, $unitCodes = [] , $deployType = 'section')
    {
        $condition = [
            'status' => UnitService::STATUS_ENABLED,
        ];
        if (!empty($unitCodes)) {
            $condition['unit_code'] = $unitCodes;
        } else {
            $condition['district_code'] = $districtCode;
            $condition['event_type3_code'] = $eventTypes;
            if (!empty($streetCode)) {
                $condition['street_code'] = $streetCode;
            }
            if (!empty($communityCode)) {
                $condition['community_code'] = $communityCode;
            }
            if (!empty($estateCode)) {
                $condition['estate_code'] = $estateCode;
            }
            if (!empty($gridCode)) {
                if ($deployType == 'grid') {
                    $condition['grid_code'] = $gridCode;
                } else {
                    $section = Section::findOne(['code' => $gridCode]);
                    $condition['section'] = $section->name;
                    $condition['section_start'] = $section->start;
                    $condition['section_end'] = $section->end;
                }
            }
        }

        $count = 0;
        $query = Unit::find()->where($condition);
        $bindCount = 0;
        foreach ($query->batch() as $rows) {
            $items = [];
            foreach ($rows as $row) {
                if ($row['has_bind']) {
                    $bindCount++;
                }
                $items[] = [
                    'deploy_id' => $plan->id,
                    'district' => $row['district_code'],
                    'street' => $row['street_code'],
                    'community_code' => $row['community_code'] ?? '',
                    'estate_code' => $row['estate_code'] ?? '',
                    'grid_code' => $row['grid_code'],
                    'section' => $deployType == 'section' ? $section->code : '',
                    'event_type1_code' => $row['event_type1_code'],
                    'event_type2_code' => $row['event_type2_code'],
                    'event_type3_code' => $row['event_type3_code'],
                    'unit_name_code' => $row['name_code'],
                    'unit_code' => $row['unit_code'],
                    'state' => $row['has_bind'] ? 1 : 0,
                ];
            }
            Yii::$app->test_3->createCommand()
                                ->batchInsert(DeployDetail::tableName(), array_keys($items[0]), $items)
                                ->execute();
            $count += count($items);
            unset($items);
        }

        return [$count, $bindCount];
    }

    public function search($params)
    {
        $query = $this->genQuery($params);
        return new ActiveDataProvider([
            'query' => $query,
            'pagination' => new Pagination([
                'pageSize' => $params['per-page'],
                'page' => $params['page'] - 1,
            ]),
            'sort' => false
        ]);
    }

    public function export($params)
    {
        $title = '序号,部署日期,部署人,部署区,部署街道数量,部署网格数量,部件类型数量,部件数量,绑码部件数量,绑码率,部署状态';
        $header = explode(',', $title);
        $query = $this->genQuery($params);
        $rows = [];
        foreach ($query->each() as $item) {
            $rows[] = [
                'id' => $item['id'],
                'createdAt' => chr(0x1E) . $item['created_at'],
                'userId' => $item['user_name'],
                'districtName' => $item['district_name'],
                'streetCount' => $item['street_count'],
                'gridCount' => $item['grid_count'],
                'eventTypeCount' => $item['event_type_count'],
                'unitCount' => $item['unit_count'],
                'bindUnitCount' => $item['bind_unit_count'],
                'bindRate' => empty($item['unit_count']) ? 0 : sprintf('%.2f', $item['bind_unit_count'] / $item['unit_count']),
                'state' => $item['state'] ? '已完成' : '进行中',
            ];
        }
        $filename = 'export_' . date('Y-m-d') . '_' . uniqid() . '.csv';

        $file = ExportUtil::exportCsv($filename, $header, $rows);
        $localPath = '/exportfile/'.date('Y-m-d').'/'.$filename;
        return ['url' => $localPath];

//        if (YII_ENV == 'prod' || YII_ENV == 'uat') {
//            $response = Yii::$app->fileServer->uploadFile($file);
//            @unlink($file->getRealPath());
//        }
//
//        return [
//            'url' => $response['path'] ?? "exportfile/${filename}",
//        ];


    }

    private function genQuery($params): Query
    {
        $conditions = [];
        if (!StringUtil::isEmpty($params['state'])) {
            $conditions[] = ['state' => $params['state']];
        }
        $query = QrcodeDeploy::find();
        foreach ($conditions as $condition) {
            $query->andFilterWhere($condition);
        }
        $subQuery = $this->genDetailQuery($params);
        if (!empty($subQuery)) {
            $query->andFilterWhere(['id' => $subQuery]);
        }

        return $query->orderBy(['id' => SORT_DESC]);
    }

    private function genDetailQuery($params)
    {
        $conditions = [];
        if (!StringUtil::isEmpty($params['district'])) {
            $conditions[] = ['district' => $params['district']];
        }
        if (!StringUtil::isEmpty($params['meta_level3'])) {
            $conditions[] = ['district' => $params['meta_level3']];
        }
        if (!StringUtil::isEmpty($params['street'])) {
            $conditions[] = ['street' => $params['street']];
        }
        if (!StringUtil::isEmpty($params['meta_level4'])) {
            $conditions[] = ['street' => $params['meta_level4']];
        }
        if (!StringUtil::isEmpty($params['meta_level5'])) {
            $conditions[] = ['community_code' => $params['meta_level5']];
        }
        if (!StringUtil::isEmpty($params['meta_level6'])) {
            $conditions[] = ['estate_code' => $params['meta_level6']];
        }
        if (!StringUtil::isEmpty($params['gridCenter'])) {
            $conditions[] = ['grid_code' => $params['gridCenter']];
        }
        if (!StringUtil::isEmpty($params['eventType'])) {
            $conditions[] = ['event_type3_code' => $params['eventType']];
        }
        if (empty($conditions)) {
            return null;
        }
        $query = DeployDetail::find();
        foreach ($conditions as $condition) {
            $query->andFilterWhere($condition);
        }
        return $query->select(['deploy_id']);
    }

    public static function getUnitCodes($params)
    {
        $condition = [];
        if (!empty($params['district_code'])) {
            $condition['district'] = $params['district_code'];
        }
        if (!empty($params['street_code'])) {
            $condition['street'] = $params['street_code'];
        }
        if (!StringUtil::isEmpty($params['meta_level3'])) {
            $conditions[] = ['district' => $params['meta_level3']];
        }
        if (!StringUtil::isEmpty($params['meta_level4'])) {
            $conditions[] = ['street' => $params['meta_level4']];
        }
        if (!StringUtil::isEmpty($params['meta_level5'])) {
            $conditions[] = ['community_code' => $params['meta_level5']];
        }
        if (!StringUtil::isEmpty($params['meta_level6'])) {
            $conditions[] = ['estate_code' => $params['meta_level6']];
        }
        if (!empty($params['grid_code'])) {
            $condition['grid_code'] = $params['grid_code'];
        }
        if (!empty($params['section_code'])) {
            $condition['section'] = $params['section_code'];
        }
        if (!empty($params['event_type3_code'])) {
            $condition['event_type3_code'] = $params['event_type3_code'];
        }
        if (!empty($params['deploy_id'])) {
            $condition['deploy_id'] = $params['deploy_id'];
        }
        return DeployDetail::find()->where($condition)->select(['unit_code'])->all();
    }
}
